#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试运行器

一键运行调度系统的所有测试脚本，包括：
- API接口测试
- 认证测试
- 工单管理测试
- 性能测试

使用方法：
python run_tests.py [test_type]

test_type 可选值：
- all: 运行所有测试（默认）
- api: 仅运行API接口测试
- auth: 仅运行认证测试
- workorder: 仅运行工单管理测试
- performance: 仅运行性能测试
"""

import sys
import os
import subprocess
import time
from datetime import datetime

# 测试脚本配置
TEST_SCRIPTS = {
    'auth': {
        'file': 'auth_test.py',
        'name': '认证模块测试',
        'description': '测试用户登录、获取信息、修改密码等认证功能'
    },
    'api': {
        'file': 'api_test_suite.py',
        'name': 'API接口测试套件',
        'description': '测试所有API接口的完整功能'
    },
    'workorder': {
        'file': 'work_order_test.py',
        'name': '工单管理专项测试',
        'description': '测试工单CRUD、自定义字段、处理记录等功能'
    },
    'performance': {
        'file': 'performance_test.py',
        'name': '性能测试',
        'description': '测试API响应时间、并发性能、压力测试等'
    }
}

class TestRunner:
    def __init__(self):
        self.test_results = {}
        self.start_time = None
        self.end_time = None
        
    def check_dependencies(self):
        """检查测试依赖"""
        print("检查测试环境...")
        
        # 检查Python模块
        required_modules = ['requests', 'psutil']
        missing_modules = []
        
        for module in required_modules:
            try:
                __import__(module)
                print(f"✓ {module} 模块已安装")
            except ImportError:
                missing_modules.append(module)
                print(f"✗ {module} 模块未安装")
        
        if missing_modules:
            print(f"\n请安装缺失的模块: pip install {' '.join(missing_modules)}")
            return False
        
        # 检查测试脚本文件
        missing_scripts = []
        for test_type, config in TEST_SCRIPTS.items():
            script_path = config['file']
            if not os.path.exists(script_path):
                missing_scripts.append(script_path)
                print(f"✗ 测试脚本 {script_path} 不存在")
            else:
                print(f"✓ 测试脚本 {script_path} 存在")
        
        if missing_scripts:
            print(f"\n缺失测试脚本: {', '.join(missing_scripts)}")
            return False
        
        print("✓ 测试环境检查通过\n")
        return True
    
    def run_single_test(self, test_type):
        """运行单个测试"""
        if test_type not in TEST_SCRIPTS:
            print(f"✗ 未知的测试类型: {test_type}")
            return False
        
        config = TEST_SCRIPTS[test_type]
        script_file = config['file']
        test_name = config['name']
        
        print(f"\n{'='*60}")
        print(f"开始运行: {test_name}")
        print(f"脚本文件: {script_file}")
        print(f"描述: {config['description']}")
        print(f"{'='*60}")
        
        start_time = time.time()
        
        try:
            # 运行测试脚本
            result = subprocess.run(
                [sys.executable, script_file],
                capture_output=True,
                text=True,
                timeout=300  # 5分钟超时
            )
            
            end_time = time.time()
            duration = end_time - start_time
            
            # 记录结果
            self.test_results[test_type] = {
                'name': test_name,
                'success': result.returncode == 0,
                'duration': duration,
                'stdout': result.stdout,
                'stderr': result.stderr,
                'return_code': result.returncode
            }
            
            if result.returncode == 0:
                print(f"\n✓ {test_name} 执行成功 (耗时: {duration:.2f}秒)")
                # 显示测试输出的最后几行
                output_lines = result.stdout.strip().split('\n')
                if len(output_lines) > 5:
                    print("\n测试结果摘要:")
                    for line in output_lines[-5:]:
                        if line.strip():
                            print(f"  {line}")
            else:
                print(f"\n✗ {test_name} 执行失败 (耗时: {duration:.2f}秒)")
                print(f"返回码: {result.returncode}")
                if result.stderr:
                    print(f"错误信息: {result.stderr}")
            
            return result.returncode == 0
            
        except subprocess.TimeoutExpired:
            print(f"\n✗ {test_name} 执行超时")
            self.test_results[test_type] = {
                'name': test_name,
                'success': False,
                'duration': 300,
                'error': 'Timeout'
            }
            return False
            
        except Exception as e:
            print(f"\n✗ {test_name} 执行异常: {e}")
            self.test_results[test_type] = {
                'name': test_name,
                'success': False,
                'duration': 0,
                'error': str(e)
            }
            return False
    
    def run_tests(self, test_types):
        """运行指定的测试"""
        self.start_time = time.time()
        
        print(f"开始运行测试: {', '.join(test_types)}")
        print(f"开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        
        # 检查环境
        if not self.check_dependencies():
            return False
        
        success_count = 0
        total_count = len(test_types)
        
        # 运行测试
        for test_type in test_types:
            if self.run_single_test(test_type):
                success_count += 1
        
        self.end_time = time.time()
        total_duration = self.end_time - self.start_time
        
        # 输出总结
        self.print_summary(success_count, total_count, total_duration)
        
        return success_count == total_count
    
    def print_summary(self, success_count, total_count, total_duration):
        """打印测试总结"""
        print(f"\n\n{'='*80}")
        print("测试执行总结")
        print(f"{'='*80}")
        
        print(f"执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"总耗时: {total_duration:.2f}秒")
        print(f"测试总数: {total_count}")
        print(f"成功: {success_count}")
        print(f"失败: {total_count - success_count}")
        print(f"成功率: {(success_count/total_count*100):.1f}%")
        
        print(f"\n详细结果:")
        for test_type, result in self.test_results.items():
            status = "✓" if result['success'] else "✗"
            duration = result.get('duration', 0)
            print(f"  {status} {result['name']} (耗时: {duration:.2f}秒)")
            
            if not result['success'] and 'error' in result:
                print(f"    错误: {result['error']}")
        
        # 保存详细报告
        self.save_test_report()
        
        if success_count == total_count:
            print(f"\n🎉 所有测试执行成功！")
        else:
            print(f"\n⚠️  有 {total_count - success_count} 个测试失败")
    
    def save_test_report(self):
        """保存测试报告"""
        import json
        
        report_data = {
            "test_summary": {
                "start_time": datetime.fromtimestamp(self.start_time).isoformat(),
                "end_time": datetime.fromtimestamp(self.end_time).isoformat(),
                "total_duration": self.end_time - self.start_time,
                "total_tests": len(self.test_results),
                "successful_tests": sum(1 for r in self.test_results.values() if r['success']),
                "failed_tests": sum(1 for r in self.test_results.values() if not r['success'])
            },
            "test_results": self.test_results
        }
        
        report_file = f"test_execution_report_{int(time.time())}.json"
        with open(report_file, 'w', encoding='utf-8') as f:
            json.dump(report_data, f, ensure_ascii=False, indent=2)
        
        print(f"\n详细测试报告已保存到: {report_file}")

def print_usage():
    """打印使用说明"""
    print("调度系统测试运行器")
    print("=" * 30)
    print("\n使用方法:")
    print("  python run_tests.py [test_type]")
    print("\n可用的测试类型:")
    print("  all         - 运行所有测试（默认）")
    
    for test_type, config in TEST_SCRIPTS.items():
        print(f"  {test_type:<12} - {config['description']}")
    
    print("\n示例:")
    print("  python run_tests.py              # 运行所有测试")
    print("  python run_tests.py auth         # 仅运行认证测试")
    print("  python run_tests.py api          # 仅运行API测试")
    print("  python run_tests.py performance  # 仅运行性能测试")

def main():
    """主函数"""
    # 解析命令行参数
    if len(sys.argv) > 1:
        test_arg = sys.argv[1].lower()
        
        if test_arg in ['help', '-h', '--help']:
            print_usage()
            return
        
        if test_arg == 'all':
            test_types = list(TEST_SCRIPTS.keys())
        elif test_arg in TEST_SCRIPTS:
            test_types = [test_arg]
        else:
            print(f"错误: 未知的测试类型 '{test_arg}'")
            print_usage()
            return
    else:
        test_types = list(TEST_SCRIPTS.keys())
    
    # 创建测试运行器并执行测试
    runner = TestRunner()
    success = runner.run_tests(test_types)
    
    # 设置退出码
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()